package com.bocloud.cmp.driver.providers.jd;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bocloud.cmp.driver.providers.BucketDriver;
import com.bocloud.cmp.driver.utils.DateConverter;
import com.bocloud.cmp.model.BucketModel;
import com.bocloud.common.model.BsmResult;
import com.google.common.collect.Lists;
import com.jcloud.jss.JingdongStorageService;
import com.jcloud.jss.domain.Bucket;
import com.jcloud.jss.domain.acl.AccessControlPolicy;
import com.jcloud.jss.exception.StorageClientException;
import com.jcloud.jss.exception.StorageServerException;

public class JdBucketDriver extends JdDriver implements BucketDriver {

	private static Logger logger = LoggerFactory.getLogger(JdBucketDriver.class);
	private JingdongStorageService jss;// 存储服务

	/**
	 * 
	 */
	public JdBucketDriver() {
	}

	/**
	 * @param accessKey
	 * @param secertkey
	 * @param endpoint
	 */
	public JdBucketDriver(String accessKey, String secretKey, String endpoint, String region) {
		super(accessKey, secretKey, endpoint, region);
		this.jss = new JingdongStorageService(this.getCredential().getJssCredential());
		this.jss.setEndpoint(endpoint);
	}

	/**
	 * @return the jss
	 */
	public JingdongStorageService getJss() {
		return jss;
	}

	/**
	 * @param jss
	 *            the jss to set
	 */
	public void setJss(JingdongStorageService jss) {
		this.jss = jss;
	}

	public BsmResult create(String bucket, boolean share) {
		if (StringUtils.isEmpty(bucket)) {
			logger.info("bucket name is empty");
			return new BsmResult(false, "bucket name is empty!");
		}
		boolean exits = jss.hasBucket(bucket);
		if (exits) {
			logger.warn("bucket [{}] already exists!", bucket);
			return new BsmResult(false, "bucket名称已存在");
		}
		try {
			jss.bucket(bucket).create();
			boolean success = jss.hasBucket(bucket);
			if (success) {
				logger.info("create bucket [{}] success!", bucket);
				if (share) {
					jss.bucket(bucket).acl().internetVisible().set();
				} else {
					jss.bucket(bucket).acl().set();
				}
				return new BsmResult(true, "success");
			} else {
				logger.error("create bucket [{}] failed!", bucket);
				return new BsmResult(false, "bucket [" + bucket + "] create failed!");
			}
		} catch (StorageClientException | StorageServerException e) {
			logger.error("create bucket [{}] exception!", e);
			return new BsmResult(false, "bucket [" + bucket + "] create failed!");
		} finally {
			this.destory();
		}
	}

	@Override
	public BsmResult exists(String bucket) {
		try {
			boolean exist = jss.hasBucket(bucket);
			return new BsmResult(exist, exist + "");
		} catch (StorageClientException | StorageServerException e) {
			logger.error("exists bucket [{}] exception!", e);
			return new BsmResult(false, "bucket [" + bucket + "] exists failed!");
		} finally {
			this.destory();
		}
	}

	@Override
	public void destory() {
		if (null != jss) {
			jss.destroy();
		}
	}

	@Override
	public BsmResult remove(String bucket) {
		if (StringUtils.isEmpty(bucket)) {
			logger.info("bucket name is empty");
			return new BsmResult(false, "bucket name is empty!");
		}
		boolean exits = jss.hasBucket(bucket);
		if (!exits) {
			logger.warn("bucket [{}] does not exists! ", bucket);
			return new BsmResult(false, "bucket名称不存在");
		}
		try {
			jss.bucket(bucket).acl().delete();
			jss.bucket(bucket).delete();
			boolean success = jss.hasBucket(bucket);
			if (!success) {
				logger.info("remove bucket [{}] success!", bucket);
				return new BsmResult(true, "success");
			} else {
				logger.error("remove bucket [{}] failed!", bucket);
				return new BsmResult(false, "bucket [" + bucket + "] remove failed!");
			}
		} catch (StorageClientException | StorageServerException e) {
			logger.error("remove bucket [{}] exception!", e);
			return new BsmResult(false, "bucket [" + bucket + "] remove failed!");
		} finally {
			this.destory();
		}

	}

	@Override
	public BsmResult detail(String bucket) {
		if (StringUtils.isEmpty(bucket)) {
			logger.info("bucket name is empty");
			return new BsmResult(false, "bucket name is empty!");
		}
		boolean exits = jss.hasBucket(bucket);
		if (!exits) {
			logger.warn("bucket [{}] does not exists! ", bucket);
			return new BsmResult(false, "bucket名称不存在");
		}

		try {
			List<Bucket> list = jss.listBucket();
			BucketModel model = null;
			if (null == list || list.isEmpty()) {
				return new BsmResult(true, model, "success");
			}
			for (Bucket bean : list) {
				if (bean.getName().equals(bucket)) {
					// 空间大小
					BigDecimal decimal = new BigDecimal(jss.bucket(bucket).getBucketSpace());
					double space = decimal.divide(new BigDecimal(1024 * 1024), 2, RoundingMode.HALF_UP).doubleValue();
					// 公有私有
					AccessControlPolicy policy = jss.bucket(bucket).acl().get();
					model = new BucketModel(bucket, space, bean.getLocation(), policy.isInternetVisible(),
							DateConverter.stringToDate(bean.getCreationDate()));

					break;
				}
			}
			return new BsmResult(true, model, "success");
		} catch (StorageClientException | StorageServerException e) {
			logger.error("Get bucket [{}] exception!", e);
			return new BsmResult(false, "Get bucket failed!");
		} finally {
			this.destory();
		}
	}

	@Override
	public BsmResult list() {
		try {
			List<Bucket> list = jss.listBucket();
			List<BucketModel> models = Lists.newArrayList();
			if (null == list || list.isEmpty()) {
				return new BsmResult(true, models, "success");
			}
			for (Bucket bean : list) {
				// 空间大小
				BigDecimal decimal = new BigDecimal(jss.bucket(bean.getName()).getBucketSpace());
				double space = decimal.divide(new BigDecimal(1024 * 1024), 2, RoundingMode.HALF_UP).doubleValue();
				// 公有私有
				AccessControlPolicy policy = jss.bucket(bean.getName()).acl().get();
				BucketModel model = new BucketModel(bean.getName(), space, bean.getLocation(),
						policy.isInternetVisible(), DateConverter.stringToDate(bean.getCreationDate()));
				models.add(model);
			}
			return new BsmResult(true, models, "success");
		} catch (StorageClientException | StorageServerException e) {
			logger.error("List bucket [{}] exception!", e);
			return new BsmResult(false, "List bucket failed!");
		} finally {
			this.destory();
		}
	}

	@Override
	public BsmResult acl(String bucket, boolean share) {
		try {
			BsmResult result = this.exists(bucket);
			if (!result.isSuccess()) {
				return result;
			}
			if (share) {
				jss.bucket(bucket).acl().internetVisible();
			} else {
				jss.bucket(bucket).acl().set();
			}
			return new BsmResult(true, "success");
		} catch (StorageClientException | StorageServerException e) {
			logger.error("set bucket [{}] acl [{}] exception!", bucket, share, e);
			return new BsmResult(false, "set bucket acl failed!");
		} finally {
			this.destory();
		}
	}

}
